#!/usr/bin/env python
#
# Copyright 2013 Google Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Administrative tools for managing Wi-Fi probes and the dashboard."""
__author__ = "Joey Freeland (joeyfreeland@gmail.com)"

from datetime import datetime
import os

import webapp2

import models

from google.appengine.ext import db
from google.appengine.api import users
from google.appengine.ext.webapp import template


class AddTimeSinceLastResult(webapp2.RequestHandler):
  """Update results to add the time since last result was posted."""

  def get(self):
    if users.is_current_user_admin():
      r = self.request
      location, provider, ssid = (r.get("location"), r.get("provider"),
                                  r.get("ssid"))
      if location and provider and ssid:
        query = (db.Query(models.TestResult)
                 .filter("location = ", location)
                 .filter("provider = ", provider)
                 .filter("ssid = ", ssid)
                 .filter("time_since_last_result =", None)
                 .order("date"))
        count = 0
        last_result_time = None
        for test_result in query.run():
          if last_result_time is None:
            last_result_time = test_result.date
          else:
            tslr = test_result.date - last_result_time
            test_result.time_since_last_result = str(tslr.seconds)
            test_result.put()
            count += 1
            last_result_time = test_result.date
        self.redirect(("/lumberg?tslr=1&location=%s&provider=%s&count=%s") %
                      (location, provider, count))
      else:
        self.response.out.write("Location and provider were not provided.")
    else:
      self.response.out.write("Invalid user.")


class AdminPage(webapp2.RequestHandler):
  """Display the admin page if the user is an authenticated user."""

  def get(self):
    if users.is_current_user_admin():
      r = self.request
      attributes = self.request.arguments()
      template_values = {}
      for a in attributes:
        template_values[a] = r.get(a)
      path = os.path.join(os.path.dirname(__file__), "templates/admin.html")
      self.response.out.write(template.render(path, template_values))


class DeleteDevice(webapp2.RequestHandler):
  """Delete a wireless testing device based on the location name."""

  def get(self):
    if users.is_current_user_admin():
      r = self.request
      location = r.get("location")
      if location:
        test_results = models.TestResult.all().filter("location = ", location)
        for test_result in test_results:
          test_result.delete()
        device_results = models.WiFiTestingDevice.all()
        device_results.filter("device_name = ", location)
        for device_result in device_results:
          device_result.delete()
        self.redirect("/lumberg?devicedeleted=1&deleteddevice=%s" % location)
      else:
        self.response.out.write("Did not receive a location ID.")
    else:
      self.response.out.write("Invalid user.")


class DeleteResults(webapp2.RequestHandler):
  """Delete test results with a date prior to the date specified."""

  def get(self):
    if users.is_current_user_admin():
      # TODO(joeyfreeland): Allow the date to be passed to this class.
      delete_date = datetime.today()
      results = models.TestResult.all().filter("date < ", delete_date)
      for result in results:
        result.delete()
      self.redirect("/lumberg?resultsdeleted=1")
    else:
      self.response.out.write("Invalid user.")


class UpdateDeviceAndResults(webapp2.RequestHandler):
  """Update a device provider, location, and results for a particular device."""

  def get(self):
    if users.is_current_user_admin():
      r = self.request
      old_location = r.get("old_location")
      new_location = r.get("new_location")
      new_provider = r.get("new_provider")
      if old_location and new_location:
        check_name = models.WiFiTestingDevice.all()
        existing_device = (check_name.filter("device_name = ", new_location)
                           .get())
        if existing_device:
          self.response.out.write("This name already exists.")
          return
        else:
          device_results = models.WiFiTestingDevice.all()
          device_result = (device_results
                           .filter("device_name = ", old_location).get())
          old_version = device_result.config_version.split(".")
          old_version[2] = int(old_version[2]) + 1
          device_result.config_version = ".".join([str(i) for i in old_version])
          if new_provider:
            device_result.device_name = new_location
            device_result.provider = new_provider
            device_result.put()
          else:
            device_result.device_name = new_location
            device_result.put()
          test_results = models.TestResult.all().filter("location = ",
                                                        old_location)
          if new_provider:
            for test_result in test_results:
              test_result.location = new_location
              test_result.provider = new_provider
              test_result.put()
          else:
            for test_result in test_results:
              test_result.location = new_location
              test_result.put()
          self.redirect(("/lumberg?deviceupdated=1&old_location=%s&new_location"
                         "=%s") % (old_location, new_location))
      else:
        self.response.out.write("Invalid query.")
    else:
      self.response.out.write("Invalid user.")


app = webapp2.WSGIApplication([("/lumberg", AdminPage),
                               ("/lumberg/addtslr", AddTimeSinceLastResult),
                               ("/lumberg/deletedevice", DeleteDevice),
                               ("/lumberg/deleteresults", DeleteResults),
                               ("/lumberg/updatedevice",
                                UpdateDeviceAndResults),
                              ],
                              debug=True)


def main():
  app.run()


if __name__ == "__main__":
  main()
